/**
 *Copyright (c) 2024 watereyes
 * safetymanagement is licensed under Mulan PubL v2.
 * You can use this software according to the terms and conditions of the Mulan
 * PubL v2.
 * You may obtain a copy of Mulan PubL v2 at:
 *          http://license.coscl.org.cn/MulanPubL-2.0
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PubL v2 for more details.
 */
package com.koron.risk.service.impl;


import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import com.koron.common.Tools;
import com.koron.common.bean.DepartmentTreeBean;
import com.koron.common.bean.GroupBean;
import com.koron.common.bean.SecretBean;
import com.koron.common.bean.StaffBean;
import com.koron.common.dfs.FastDFSClientWrapper;
import com.koron.common.domain.DataBean;
import com.koron.common.stub.Port;
import com.koron.risk.bean.CorpBean;
import com.koron.risk.bean.KeyWorkDetail;
import com.koron.risk.mapper.CorpManagementMapper;
import com.koron.risk.mapper.KeyWorkMapper;
import com.koron.risk.service.api.CorpManagementService;
import com.koron.risk.util.BusinessCode;
import com.koron.risk.util.Constants;
import org.apache.commons.lang3.StringUtils;
import org.koron.ebs.mybatis.ADOSessionImpl;
import org.koron.ebs.mybatis.SessionFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.swan.bean.MessageBean;

import java.math.BigDecimal;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
@PropertySource(value = "classpath:lal.properties", encoding = "UTF-8")
public class CorpManagementServiceImpl implements CorpManagementService {

    private final static Logger logger= LoggerFactory.getLogger(CorpManagementServiceImpl.class);
    @Value("${app.orgCode:}")
    private String orgCode;

    @Value("${app.defaultRole:}")
    private String defaultRoleCode;   //默认角色code

    @Value("${app.appid:}")
    private String appid;

    @Value("${app.secret:}")
    private String secret;

    @Value("${longitude_latitude}")
    private String longitude_latitude;

    @Autowired
    private FastDFSClientWrapper clientWrapper;

    /**
     * 公司code-name
     */
    public Map<String, String> codeNameMap = new HashMap<String, String>();

    @SuppressWarnings({"rawtypes", "unchecked"})
    public MessageBean<DataBean<CorpBean>> corpList(Integer page, Integer pageSize, List<String> excludeFilter) {
        MessageBean<DataBean<CorpBean>> msg = new MessageBean<>();
        Integer totalPage = null;
        Integer totalNumber = null;
        Integer start = null;
        Integer end = null;
        if (null != page && pageSize != null) {
            if (page > 0 && pageSize > 0) {
            } else {
                //第一页 10条数据
                page = 1;
                pageSize = 10;
            }
            start = (page <= 1) ? 0 : (page - 1) * pageSize;
            end = pageSize * page;
        }
        Port port = getPort();
        MessageBean<List> deptMsg = port.depttree(orgCode, null, 1);    //组织列表
        List<DepartmentTreeBean> deptList = deptMsg.getData();
        List<CorpBean> list = new ArrayList<CorpBean>();
        for (DepartmentTreeBean bean : deptList) {        //过滤出公司
            if ((bean.getDeptType() & 16) == 16) {
                CorpBean corpBean = new CorpBean();
                corpBean.setCorpCode(bean.getDepartmentCode());
                corpBean.setCorpName(bean.getName());
                list.add(corpBean);
            }
        }

        if (Objects.nonNull(excludeFilter) && !excludeFilter.isEmpty()) {
            list = list.stream().filter(corpBean -> !excludeFilter.contains(corpBean.getCorpCode())).collect(Collectors.toList());
        }

        totalNumber = list.size();
        SessionFactory factory = null;
        try {
            factory = new ADOSessionImpl().getSessionFactory();
            List<CorpBean> cList = factory.getMapper(CorpManagementMapper.class).list();
            Map<String, CorpBean> maps = cList.stream().collect(Collectors.toMap(CorpBean::getCorpCode, a -> a, (k1, k2) -> k1));
            for (CorpBean corpBean : list) {
                if (maps.containsKey(corpBean.getCorpCode())) {
                    corpBean.setAddTime(maps.get(corpBean.getCorpCode()).getAddTime());
                    corpBean.setDescription(maps.get(corpBean.getCorpCode()).getDescription());
                    corpBean.setAttachment(maps.get(corpBean.getCorpCode()).getAttachment());
                    corpBean.setLongitude(maps.get(corpBean.getCorpCode()).getLongitude());
                    corpBean.setLatitude(maps.get(corpBean.getCorpCode()).getLatitude());
                    corpBean.setGeneralManager(maps.get(corpBean.getCorpCode()).getGeneralManager());
                    corpBean.setGeneralManagerName(maps.get(corpBean.getCorpCode()).getGeneralManagerName());
                    corpBean.setChairman(maps.get(corpBean.getCorpCode()).getChairman());
                    corpBean.setChairmanName(maps.get(corpBean.getCorpCode()).getChairmanName());
                    corpBean.setMssGeneralManager(maps.get(corpBean.getCorpCode()).getMssGeneralManager());
                    corpBean.setMssGeneralManagerName(maps.get(corpBean.getCorpCode()).getMssGeneralManagerName());
                }
            }
            Collections.sort(list, new Comparator<CorpBean>() {
                @Override
                public int compare(CorpBean o1, CorpBean o2) {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                    if (StringUtils.isNotEmpty(o1.getAddTime())) {
                        if (StringUtils.isNotEmpty(o2.getAddTime())) {
                            Date date1 = null;
                            Date date2 = null;
                            try {
                                date1 = format.parse(o1.getAddTime());
                                date2 = format.parse(o2.getAddTime());
                            } catch (ParseException e) {
                                logger.error(e.getMessage(),e);
                            }
                            return date2.compareTo(date1);
                        } else {
                            return -1;
                        }
                    } else {
                        if (StringUtils.isNotEmpty(o2.getAddTime())) {
                            return 1;
                        } else {
                            return 0;
                        }
                    }
                }
            });
            if (end != null && start != null) {
                if (end > totalNumber) {
                    end = totalNumber;
                    if (start > end) {
                        start = end;
                    }
                }
                list = list.subList(start, end);
                totalPage = totalNumber / pageSize + 1;
            } else {
                totalPage = 1;
                page = totalPage;
                pageSize = totalNumber;
            }
            DataBean data = new DataBean();
            data.setList(list);
            data.setPageNo(page);
            data.setPageSize(pageSize);
            data.setTotalNumber(totalNumber);
            data.setTotalPage(totalPage);
            msg.setData(data);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @SuppressWarnings({"unchecked", "rawtypes"})
    public MessageBean<?> openCorp(String corpCode, String corpName, StaffBean user) {
        MessageBean<?> msg = MessageBean.create(0, "success", void.class);
        SessionFactory factory = null;
        try {
            factory = new ADOSessionImpl().getSessionFactory();
            Integer count = factory.getMapper(CorpManagementMapper.class).queryAppCorp(corpCode);
            if (count > 0) {
                msg.setCode(11001);
                msg.setDescription("该公司已开通");
                factory.close(false);
                return msg;
            }
            Port port = getPort();

            //获取部门列表
            List<DepartmentTreeBean> deptList = port.depttree(orgCode, corpCode, 1).getData();
            if (deptList == null) {
                msg.setCode(11001);
                msg.setDescription("操作失败,无此公司。");
                factory.close(false);
                return msg;
            }
            String shortCode = deptList.get(0).getId().toString();
            String groupCode = "";
            String groupName = corpName + "普通员工";
            Map map = port.getGroups(1, -1, groupName).getData();    //获取应用群组列表按名称过滤
            List<GroupBean> groupList = (List) map.get("list");
            if (groupList == null) {
                //新建群组
                JSONObject attr = new JSONObject();
                attr.put("corpCode", corpCode);
                MessageBean<?> groupAddMsg = port.groupAdd(groupName, attr.toString());
                if (0 == groupAddMsg.getCode() && "success".equals(groupAddMsg.getDescription())) {//群组新增成功
                    groupCode = (String) groupAddMsg.getData();
                } else {
                    msg.setCode(11002);
                    msg.setDescription("操作失败,权限配置异常。");
                    factory.close(false);
                    return msg;
                }
            } else {
                //获得群组信息
                groupCode = groupList.get(0).getCode();
            }
            if (StringUtils.isEmpty(groupCode)) {
                msg.setCode(11002);
                msg.setDescription("操作失败,权限配置异常。");
                factory.close(false);
                return msg;
            }
            String[] targetCode = {groupCode};
            //群组关联默认角色
            port.addRelation(defaultRoleCode, targetCode, 1028);
            List<String> targetCodes = deptList.stream().map(DepartmentTreeBean::getDepartmentCode).toList();
            //群组关联部门
            port.addRelation(groupCode, targetCodes.toArray(new String[targetCodes.size()]), 514);
            //从配置文件中获取经纬度信息
            JSONObject jsonObject = JSONObject.parseObject(longitude_latitude);
            String realLongitudeLatitude = (String) jsonObject.get(corpName);
            String longitude = StringUtils.isNotEmpty(realLongitudeLatitude) ? realLongitudeLatitude.split("[,，]")[0] : null;
            String latitude = StringUtils.isNotEmpty(realLongitudeLatitude) ? realLongitudeLatitude.split("[,，]")[1] : null;
            CorpBean bean = new CorpBean();
            bean.setId(Tools.getCode32());
            bean.setAddUser(user.getCode());
            SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            bean.setAddTime(df.format(System.currentTimeMillis()));
            bean.setCorpCode(corpCode);
            bean.setCorpName(corpName);
            bean.setShortCode(shortCode);
            bean.setLatitude(latitude == null ? null : new BigDecimal(latitude));
            bean.setLongitude(longitude == null ? null : new BigDecimal(longitude));
            count = factory.getMapper(CorpManagementMapper.class).insertCorp(bean);
            if (count != 1) {
                factory.close(false);
                msg.setCode(11003);
                msg.setDescription("操作失败,数据库异常。");
                return msg;
            }
        } catch (Exception e) {
        	factory.close(false);
            msg.setCode(11003);
            msg.setDescription("操作失败,数据库异常。");
            return msg;
        } finally {
            if (factory != null) {
                factory.close();
            }
        }
        return msg;
    }

    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<Integer> update(CorpBean corpBean, MultipartFile[] files, String keepAddress, String delAddress) {
        MessageBean<Integer> msg = new MessageBean<>();
        if (StringUtils.isEmpty(corpBean.getGeneralManager()) || StringUtils.isEmpty(corpBean.getGeneralManagerName())
                || StringUtils.isEmpty(corpBean.getChairman()) || StringUtils.isEmpty(corpBean.getChairmanName())
                || StringUtils.isEmpty(corpBean.getMssGeneralManager()) || StringUtils.isEmpty(corpBean.getMssGeneralManagerName())) {
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription("公司领导信息不完整！");
            return msg;
        }
        List<String> keepList = new ArrayList<>();
        if (StringUtils.isNotEmpty(keepAddress)) {
            keepList.addAll(Arrays.asList(keepAddress.split("[,，]")));
        }
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(corpBean.getCorpCode())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_CORP_EMPTY_NO_CHANGE_DATA);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_CORP_EMPTY_NO_CHANGE_DATA);
                return msg;
            }
            CorpBean entity = factory.getMapper(CorpManagementMapper.class).get(corpBean.getCorpCode());
            if (null == entity) {
                msg.setCode(BusinessCode.MESSAGE_CODE_CORP_EMPTY_NO_CHANGE_DATA);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_CORP_EMPTY_NO_CHANGE_DATA);
                return msg;
            }
            if (null != files && files.length > 0) {
                for (MultipartFile file : files) {
                    String url = clientWrapper.uploadFile(file);
                    keepList.add(url + "#" + file.getOriginalFilename());
                }
            }
            if (null != keepList && keepList.size() > 0) {
                corpBean.setAttachment(new Gson().toJson(keepList));
            }
            Integer value = factory.getMapper(CorpManagementMapper.class).update(corpBean);
            if (value > 0) {
                if (StringUtils.isNotEmpty(delAddress)) {
                    String[] delArray = delAddress.split("[,，]");
                    for (String att : delArray) {
                        clientWrapper.deleteFile(att.split("#")[0]);
                    }
                }
                msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
                msg.setDescription("保存成功");
                msg.setData(value);
                return msg;
            } else {
                if (keepList != null && keepList.size() > 0) {
                    List<String> keepArray = StringUtils.isEmpty(keepAddress) ? new ArrayList<>() : Arrays.asList();
                    for (String att : keepList) {
                        if (!keepArray.contains(att)) {
                            clientWrapper.deleteFile(att);
                        }
                    }
                }
            }
            return msg;
        } catch (Exception e) {
            if (keepList != null && keepList.size() > 0) {
                List<String> keepArray = StringUtils.isEmpty(keepAddress) ? new ArrayList<>() : Arrays.asList();
                for (String att : keepList) {
                    if (!keepArray.contains(att)) {
                        clientWrapper.deleteFile(att);
                    }
                }
            }
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public List<CorpBean> corpBeanList() {
        try (SessionFactory factory = new SessionFactory()) {
            return factory.getMapper(CorpManagementMapper.class).list();
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<CorpBean> getOne(String code) {
        MessageBean<CorpBean> msg = new MessageBean<>();
        try (SessionFactory factory = new SessionFactory()) {
            if (StringUtils.isEmpty(code)) {
                msg.setCode(BusinessCode.MESSAGE_CODE_SERVICE_EXCEPTION);
                msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_SERVICE_EXCEPTION);
                return msg;
            }
            CorpBean bean = factory.getMapper(CorpManagementMapper.class).get(code);
            msg.setCode(BusinessCode.MESSAGE_CODE_SUCCESS);
            msg.setDescription("查看水司详情成功");
            msg.setData(bean);
            return msg;
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_EXCEPTION);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
            return msg;
        }
    }

    public Port getPort() {
        SecretBean secretBean = new SecretBean();
        secretBean.setAppid(appid);
        secretBean.setSecret(secret);
        return new Port(secretBean);
    }


    @SuppressWarnings("deprecation")
    @Override
    public MessageBean<DataBean<CorpBean>> corpOutOfDistrict(Integer page, Integer pageSize) {
        List<String> corpCodes = null;
        try (SessionFactory factory = new SessionFactory()) {
            corpCodes = factory.getMapper(CorpManagementMapper.class).noAvailableCorpCodes();
        }
        return corpList(page, pageSize, corpCodes);
    }

    @SuppressWarnings("deprecation")
    @Override
    public List<Map> queryCorpMsg() {
        List<Map> corpMsgs = new LinkedList<>();
        try (SessionFactory factory = new SessionFactory()) {
            List<CorpBean> list = factory.getMapper(CorpManagementMapper.class).list();
            Optional.ofNullable(list).ifPresent(l -> {
                KeyWorkMapper keyWorkMapper = factory.getMapper(KeyWorkMapper.class);
                l.stream().forEach(corpBean -> {
                    Map map = new HashMap();
                    map.put("id", corpBean.getId());
                    map.put("addUser", corpBean.getAddUser());
                    map.put("addTime", corpBean.getAddTime());
                    map.put("updateUser", corpBean.getUpdateUser());
                    map.put("updateTime", corpBean.getUpdateTime());
                    map.put("corpCode", corpBean.getCorpCode());
                    map.put("corpName", corpBean.getCorpName());
                    map.put("shortCode", corpBean.getShortCode());
                    map.put("description", corpBean.getDescription());
                    map.put("attachment", corpBean.getAttachment());
                    map.put("latitude", corpBean.getLatitude());
                    map.put("longitude", corpBean.getLongitude());
                    // 奥港供水：做特殊处理，新增部门
                    if (Constants.AGGS_CORPCODE.equals(corpBean.getCorpCode())) {
                        List<Map> keyWorks = keyWorkMapper.queryAGGSByCorpCode(Constants.AGGS_CORPCODE);
                        if (keyWorks != null && keyWorks.size() > 0) {
                            List<Map> mapList = new LinkedList<>();
                            for (Map keyWork : keyWorks) {
                                if (keyWork.get("departmentCode") != null && Optional.ofNullable(keyWork.get("time")).orElse("time").toString().equals(
                                        keyWorks.stream().filter(map1 -> {
                                            if (map1.get("departmentCode") == null) {
                                                return false;
                                            } else {
                                                return map1.get("departmentCode").toString().equals(keyWork.get("departmentCode").toString());
                                            }
                                        }).max((m1, m2) -> {
                                            int i = Optional.ofNullable(m1.get("time")).orElse("").toString().compareTo(
                                                    Optional.ofNullable(m2.get("time")).orElse("").toString());
                                            return i > 0 ? 1 : -1;
                                        }).get().get("time").toString()
                                )) {
                                    mapList.add(keyWork);
                                }
                            }
                            keyWorks = mapList;
                            // 过滤处理
                            for (Map keyWork : keyWorks) {
                                List<KeyWorkDetail> details = keyWorkMapper.queryByKeyWorkId(keyWork.get("id").toString());
                                keyWork.put("workList", details);
                            }
                        }
                        map.put("keyWork", keyWorks);
                    } else {
                        Map keyWork = keyWorkMapper.queryByCorpCode(corpBean.getCorpCode());
                        if (keyWork != null) {
                            List<KeyWorkDetail> details = keyWorkMapper.queryByKeyWorkId(keyWork.get("id").toString());
                            keyWork.put("workList", details);
                        }
                        map.put("keyWork", keyWork);
                    }
                    corpMsgs.add(map);
                });
            });
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return corpMsgs;
    }

    @Override
    public MessageBean queryPerMsgByCorp(String corpCode) {
        MessageBean msg = MessageBean.create(BusinessCode.MESSAGE_CODE_SUCCESS, BusinessCode.MESSAGE_DESCRIPTION_SUCCESS, void.class);
        try (SessionFactory factory = new SessionFactory()) {
            CorpManagementMapper mapper = factory.getMapper(CorpManagementMapper.class);
            CorpBean bean = mapper.get(corpCode);
            if (bean == null) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("没有获取到水司信息！");
                return msg;
            }
            if (StringUtils.isEmpty(bean.getGeneralManager())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("没有获取到水司总经理!");
                return msg;
            }
            if (StringUtils.isEmpty(bean.getChairman())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("没有获取到水司董事长!");
                return msg;
            }
            if (StringUtils.isEmpty(bean.getMssGeneralManager())) {
                msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
                msg.setDescription("没有获取到水司安全部总经理!");
                return msg;
            }
            msg.setData(bean);
        } catch (Exception e) {
            logger.error(e.getMessage(),e);
            msg.setCode(BusinessCode.MESSAGE_CODE_FAIL);
            msg.setDescription(BusinessCode.MESSAGE_DESCRIPTION_EXCEPTION);
        }
        return msg;
    }

    public Map<String, String> getCodeNameMap() {
        return codeNameMap;
    }
}
